package com;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import Fenetre.FenetrePrincipale;
import Fenetre.ProgressPanel;

import Variabilize.Variabilize;

import com.Reader.*;
import com.Clause.Clause;
import com.Clause.Biais.Biais;
import com.Comparaisons.Counter;
import com.DB.*;

/**
 * Classe principale du programme
 * @author florent
 */
public class Main {
	public static void main(String[] args){		
		
		File[] fichiers_db = {

				new File("in/famille/famille.db")

				//new File("in/univ/univ-train.db")

				/*new File("in/cora/cora1.db"),
				new File("in/cora/cora2.db"),
				new File("in/cora/cora3.db"),
				new File("in/cora/cora4.db"),
				new File("in/cora/cora5.db")*/
		};

		int seuil = 1;

		File fichier_info = new File("in/famille/famille.info");//new File("in/cora/cora.info");////new File("in/univ/univ.mln"); // //  //
		File fichier_type = new File("in/famille/famille.type");//new File("in/cora/cora.type");////null; // //null; //

		Main main = new Main();
		float time = main.executer(null,fichier_info,fichier_type,fichiers_db,seuil);

		int time_min = (int)time/60;

		System.out.println("temps: " + time+" secondes ("+(time_min)+" minutes)");
	}

	public float executer(FenetrePrincipale fenetre, File fichier_info, File fichier_type, File[] fichiers_db, int seuil){

		long begin = System.currentTimeMillis();

		boolean creer = true;

		ArrayList<Modele> modeles = null;
		ArrayList<Type> types = null;

		ArrayList<Constante> constantes = null;

		/**
		 * 
		 * LECTURE
		 * 
		 */		

		if(fenetre != null)
			fenetre.setProgressValue(ProgressPanel.LECTURE,0);
		else
			System.out.print("Lecture :");

		ReaderDB cr = new ReaderDB(fichiers_db);

		if(fichier_type != null){
			ReaderType crt = new ReaderType(fichier_type);
			crt.getTypes();
		}

		if(fichier_info != null){
			ReaderInfo cri = new ReaderInfo(fichier_info);
			cri.getModeles();
		}

		String nom_base = fichiers_db[0].getName().substring(0, fichiers_db[0].getName().lastIndexOf("."));

		constantes = Constante.getConstantes();
		ArrayList<Atom> atomes = cr.getAtomes();


		types = Type.getTypes();
		modeles = Modele.getModeles();

		if(fenetre != null)
			fenetre.setProgressValue(ProgressPanel.LECTURE,100);
		else
			System.out.println(" ok");

		if(creer){
			DBConnector db_create = new DBConnector("");
			db_create.creer(nom_base,fenetre);
		}

		DBConnector db = new DBConnector(nom_base);

		if(creer){
			TableGenerator table_generator = new TableGenerator(db,fenetre);

			table_generator.createTablesTypes(types, 2);

			table_generator.createTablesModeles(modeles,2);

			table_generator.insererConstantes(constantes, 1);

			table_generator.insererAtomes(atomes,4);

		}

		if(fenetre == null)
			System.out.print("Comptage : ");

		Counter count = new Counter(db,modeles,seuil,fenetre);
		count.compter();	

		//supprime les constantes et les atomes
		constantes = null;
		atomes = null;
		System.gc();

		if(fenetre == null)
			System.out.println(" ok");

		/**
		 * 
		 * GENERATION DU GRAPHE
		 * 
		 */

		if(fenetre == null)
			System.out.print("Generation du graphe : ");

		Graphe graphe = count.recupererGraphe();
		try {
			PrintWriter pr = new PrintWriter(new FileWriter("graphe.txt"));
			pr.println(graphe.toString());
			pr.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(fenetre != null)
			fenetre.setProgressValue(ProgressPanel.GENERATION_GRAPHE,100);
		else
			System.out.println(" ok ");

		/**
		 * 
		 * CALCUL DES POIDS
		 * 
		 */

		if(fenetre != null)
			fenetre.setProgressValue(ProgressPanel.VARIABILISATION,0);

		Variabilize variabilize = new Variabilize(db, graphe);
		ArrayList<Clause> clauses = variabilize.execute();

		if(fenetre != null)
			fenetre.setProgressValue(ProgressPanel.VARIABILISATION,100);

		if(fenetre != null)
			fenetre.afficherClauses(clauses);
		else
			for(Clause clause : clauses){
				Biais.toImplique(clause);
				System.out.print(clause+"        ");
				System.out.println(clause.toPrologString());
			}

		/**
		 * 
		 * DEDUCTION DES CLAUSES
		 * 
		 */

		long end = System.currentTimeMillis();
		float time = ((float) (end-begin)) / 1000f;

		return time;

	}
}
